﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.UI.ViewModel.Data;
using ScrumTable.UI.ViewModel.Extension;

#endregion

namespace ScrumTable.UI.ViewModel
{
    /// <summary>
    /// User story for the View model
    /// </summary>
    public class IterationViewModel : ViewModelBase, IViewModelData<Iteration>
    {

        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------
        /// <summary>
        /// The Iteration from the BL.
        /// </summary>
        private readonly Iteration _iteration;
        private double? _totalStoryPoints;
        private ObservableDomainCollection<UserStoryViewModel, UserStory> _stories;
        private ScrumViewModelData _scrumData;
        private ObservableCollection<IScrumItemViewModel<DomainBase>> _storiesRatedIteration;

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        /// <summary>
        /// Gets the original instance.
        /// </summary>
        public Iteration Original { get { return _iteration; } }

        /// <summary>
        /// Gets the id of the iteration.
        /// </summary>
        public string Id
        {
            get { return _iteration.Id; }
        }

        /// <summary>
        /// Gets or sets the name of the iteration.
        /// </summary>
        /// <value>The name.</value>
        public string Name
        {
            get { return _iteration.Name; }
            set
            {
                _iteration.Name = value;
                SendPropertyChanged("Name");
            }
        }

        /// <summary>
        /// Gets the iteration
        /// </summary>
        public Iteration Iteration
        {
            get { return _iteration; }
        }
        /// <summary>
        /// Gets the name of the parent of the iteration.
        /// </summary>
        public string Parent
        {
            get
            {
                if (_iteration.Parent == null)
                    return "...";
                return _iteration.Parent.Id;
            }
        }

        /// <summary>
        /// Gets the user stories of the iteration.
        /// </summary>
        public ObservableDomainCollection<UserStoryViewModel,UserStory> Stories
        {
            get
            {
                if(_stories==null){

                    _stories = new ObservableDomainCollection<UserStoryViewModel, UserStory>(UserStoryViewModel.GetStackRankSorter(_scrumData.ConfigManager.Config.IsStackRankDescending), _scrumData);
                    _stories.Fill(_iteration.Stories, x=>new UserStoryViewModel(x));
                }
                return _stories;
            }
        }


        /// <summary>
        /// Gets the user stories of the iteration.
        /// </summary>
        public ObservableCollection<IScrumItemViewModel<DomainBase>> ItemsOnIteration
        {
            get
            {

                if (_scrumData.CurrentIteration != null)
                {
                    var stories = from x in _iteration.Stories
                                  where _scrumData.ContainsFilter(x)
                                  select (IScrumItemViewModel<DomainBase>)new UserStoryViewModel(x);

                    if (_scrumData.ConfigManager.Config.IsBugUserStory)
                    {
                        var bug1 = from x in _iteration.Bugs
                                   where _scrumData.ContainsFilter(x)
                                   select (IScrumItemViewModel<DomainBase>)new BugViewModel(x);
                        stories = stories.Union(bug1);
                    }

                    return ViewModelItemObservableCollectionExtensions.CombineList(stories, ref _storiesRatedIteration);
                }
                return _storiesRatedIteration;
            }
        }


        /// <summary>
        /// Gets or sets the start time of the iteration.
        /// </summary>
        /// <value>The start time.</value>
        public DateTime StartTime
        {
            get { return _iteration.StartTime; }
            set
            {
                _iteration.StartTime = value;
                SendPropertyChanged("StartTime");
            }
        }

        /// <summary>
        /// Gets or sets the end time of the iteration.
        /// </summary>
        /// <value>The end time.</value>
        public DateTime EndTime
        {
            get { return _iteration.EndTime; }
            set
            {
                _iteration.EndTime = value;
                SendPropertyChanged("EndTime");
            }
        }
 
  
        /// <summary>
        /// Gets or sets the total story points for the iteration.
        /// </summary>
        /// <value>The total story points.</value>
        public double? TotalStoryPoints
        {
            get { return _totalStoryPoints; }
            set
            {
                _totalStoryPoints = value;
                SendPropertyChanged("TotalStoryPoints");
            }
        }

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="IterationViewModel"/> class.
        /// </summary>
        /// <param name="iteration">The iteration.</param>
        /// <param name="scrumData">ScrumViewModel Data.</param>
        public IterationViewModel(Iteration iteration, ScrumViewModelData scrumData)
        {
            _scrumData = scrumData;
            _iteration = iteration;
            _iteration.PropertyChanged += OnIterationPropertyChanged;
            _iteration.Stories.CollectionChanged += ItemCollectionChanged;
            _iteration.Bugs.CollectionChanged += ItemCollectionChanged;
            
        }

        /// <summary>
        /// Releases managed (c# or .net) resources.
        /// </summary>
        protected override void ReleaseManagedResources()
        {
            _iteration.PropertyChanged -= OnIterationPropertyChanged;
            _iteration.Stories.CollectionChanged -= ItemCollectionChanged;
            _iteration.Bugs.CollectionChanged -= ItemCollectionChanged;
            Stories.Dispose();
            base.ReleaseManagedResources();
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------
   

        public void UpdateTotalStoryPoints()
        {
            TotalStoryPoints = (from x in Stories
                        select x.StoryPoints).Sum();
        }

        /// <summary>
        /// Saves this instance.
        /// </summary>
        public void Save()
        {
            Original.Save();
        }
        
        public void Resort()
        {
            SendPropertyChanged("ItemsOnIteration");
        }
        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        private void ItemCollectionChanged(object sender, DomainCollectionChangedEventArgs e)
        {
            SendPropertyChanged("ItemsOnIteration");
        }


        void OnIterationPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            SendPropertyChanged(e.PropertyName);
        }

        #endregion
    }
}
